package com.yingxin.yx.framework.security;

import com.yingxin.yx.framework.security.handler.*;
import com.yingxin.yx.framework.security.matcher.AntMatchers;
import com.yingxin.yx.framework.security.matcher.filter.JwtAuthenticationTokenFilter;
import com.yingxin.yx.framework.security.provider.OpenApiAccountAuthenticationProvider;
import com.yingxin.yx.framework.security.userdetails.OpenApiAccountUserDetailsService;
import com.yingxin.yx.framework.user.core.IUserSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;

/**
 * SpringSecurity配置类
 */

@Order(120)
@Configuration
public class OpenApiAccountSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 自定义登录失败处理器
     */
    @Autowired
    private UserLoginFailureHandler userLoginFailureHandler;
    /**
     * 自定义注销成功处理器
     */
    @Autowired
    private UserLogoutSuccessHandler userLogoutSuccessHandler;
    /**
     * 自定义暂无权限处理器
     */
    @Autowired
    private UserAuthAccessDeniedHandler userAuthAccessDeniedHandler;
    /**
     * 自定义未登录的处理器
     */
    @Autowired
    private UserAuthenticationEntryPointHandler userAuthenticationEntryPointHandler;

    /**
     * antMatchers
     */
    @Autowired
    private AntMatchers antMatchers;

    @Autowired
    private IUserSupport userSupport;

    /**
     * 自定义 UserDetailsService
     */
    @Autowired(required = false)
    private OpenApiAccountUserDetailsService openApiAccountUserDetailsService;

    /**
     * 验证账户
     */
    @Autowired
    private OpenApiAccountAuthenticationProvider openApiAccountAuthenticationProvider;

    /**
     * 返回token
     */
    @Autowired
    private OpenApiAccountLoginSuccessHandler openApiAccountLoginSuccessHandler;

    /**
     * 配置登录验证逻辑
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) {
        //用户验证逻辑
        auth.authenticationProvider(openApiAccountAuthenticationProvider);
    }

    /**
     * 配置security的控制逻辑
     * @Param http 请求
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/open/api/**").authorizeRequests()
                // 不进行权限验证的请求或资源(从配置文件中读取)
                .antMatchers(antMatchers.getPatterns()).permitAll()
                // .antMatchers("/*").permitAll()
                // 其他的需要登陆后才能访问
                .anyRequest().authenticated()
                .and()
                // 配置未登录自定义处理类
                .httpBasic().authenticationEntryPoint(userAuthenticationEntryPointHandler)
                .and()
                // 配置登录地址
                .formLogin()
                .loginProcessingUrl("/open/api/login")
                //.loginPage("")
                .usernameParameter("username")
                .passwordParameter("password")
                // 配置登录成功自定义处理类
                .successHandler(openApiAccountLoginSuccessHandler)
                // 配置登录失败自定义处理类
                .failureHandler(userLoginFailureHandler)
                /*.and()
                .rememberMe()
                .userDetailsService()
                .tokenRepository()
                .tokenValiditySeconds()*/
                .and()
                // 配置登出地址
                .logout()
                .logoutUrl("/open/api/Logout")
                // 配置用户登出自定义处理类
                .logoutSuccessHandler(userLogoutSuccessHandler)
                .and()
                // 配置没有权限自定义处理类
                .exceptionHandling().accessDeniedHandler(userAuthAccessDeniedHandler)
                .and()
                // 开启跨域
                .cors()
                .and()
                // 取消跨站请求伪造防护
                .csrf().disable();
        // 基于Token不需要session
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        // 禁用缓存
        http.headers().cacheControl();
        // 添加JWT过滤器
        http.addFilter(new JwtAuthenticationTokenFilter(authenticationManager(),
            userAuthenticationEntryPointHandler, openApiAccountUserDetailsService, userSupport));
    }

    @Override
    public void configure(WebSecurity web) {
        //解决静态资源被拦截的问题
        web.ignoring().antMatchers(antMatchers.getPatterns());
    }

   /* @Bean
    CorsConfigurationSource corsConfigurationSource() {
        return httpServletRequest -> {
            CorsConfiguration cfg = new CorsConfiguration();
            cfg.addAllowedHeader("*");
            cfg.addAllowedMethod("*");
            cfg.addAllowedOrigin("*");
            cfg.setAllowCredentials(true);
            return cfg;
        };
    }*/


}